#include "../head/cmd_parse.h"
#include "../head/pswd_exam.h"
#include "client_fileOp.h"

int recvfile(int sockfd){
    train_t train;
    // 先收4字节火车头 再收火车头内容的长度，再拷贝到filename
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    char filename[4096] = {0};
    memcpy(filename,train.data,train.length);
    int fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,0666);

    off_t filesize;
    off_t cursize = 0;
    off_t lastsize = 0;
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    memcpy(&filesize,train.data,train.length);
    printf("filesize = %ld\n", filesize);
    //进度条
    off_t slice = filesize/10000;
    const int bar_width = 50;
    while(1){
        bzero(train.data,sizeof(train.data));
        recvn(sockfd,&train.length,sizeof(train.length));
        if(train.length != 1000){
            printf("train.length = %d\n", train.length);
        }
        if(train.length == 0){
            break;
        }
        cursize += train.length;
        if(cursize - lastsize > slice){
            double progress = 100.0 * cursize / filesize;
            int pos = (int)(progress * bar_width / 100);
            printf("\rReceiving:[");
            for(int i = 0;i < bar_width;i++){
                if(i < pos)
                    printf("=");
                else if(i == pos)
                    printf(">");
                else
                    printf(" ");
            }
            printf("]%5.2lf%%\r",progress);
            fflush(stdout);
            lastsize = cursize;
        }
        recvn(sockfd,train.data,train.length);
        write(fd,train.data,train.length);
    }
    printf("100.00%%\n");
    close(fd);
    return 0;
}


int main(int argc, char *argv[])
{
    //用户登录
    while(1){
        char usrName[64] = "hbin";
        char usrInput[64];
        printf("Please input the password for usr %s :\n", usrName);
        scanf("%63s",usrInput);
        if(pswd_exam(usrInput))
            break;
    }

    // ./client 192.168.225.128 12345
    ARGS_CHECK(argc, 3);
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(sockfd, -1, "socket failed");

    // 申请具体类型
    struct sockaddr_in addr;
    addr.sin_family = AF_INET; // ipv4
    addr.sin_port = htons(atoi(argv[2])); // port
    addr.sin_addr.s_addr = inet_addr(argv[1]); // ip

    int ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
    ERROR_CHECK(ret, -1, "connect failed");

    int epfd = epoll_create(1);
    struct epoll_event event;
    event.events = EPOLLIN;
    // 监听stdin
    event.data.fd = STDIN_FILENO;
    epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &event);

    // 监听服务端消息
    event.events = EPOLLIN;
    event.data.fd = sockfd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);

    train_t train;
    char buf[4096] = {0};
    char *localAddr = NULL;
    struct epoll_event readySet[1024];
    while(1){
        int readyNum = epoll_wait(epfd, readySet, 1024, -1);
        for(int i = 0; i < readyNum; i++){
            if(readySet[i].data.fd == STDIN_FILENO){
                // stdin 来消息了
                bzero(buf, sizeof(buf));
                localAddr = NULL;
                bzero(&train, sizeof(train));
                // 从缓冲区接受数据
                read(STDIN_FILENO, buf, sizeof(buf));
                // 再进行处理
                printf("enter\n");
                ret = cmd_parse(buf, &train, &localAddr);
                printf("----------\n");
                printf("localAddr = %s.\n", localAddr);
                // 然后转发给服务端
                send(sockfd, &train, sizeof(train), MSG_NOSIGNAL);
                //printf("cmd = %d\n", train.cmd);
                //printf("length = %d\n", train.length);
                //printf("data = %s\n", train.data);
            }
            if(readySet[i].data.fd == sockfd){
                // 服务端来消息
                bzero(buf, sizeof(buf));
                if(train.cmd == 5){
                    // 上传文件  
		    recv(sockfd,buf,14,0);
                    printf("buf:%s\n",buf);
                    printf("localAddr = %s\n", localAddr);

                    putsFile(sockfd, localAddr);
                }
                else if(train.cmd == 6){
                    // 下载文件
                    recv(sockfd,buf,14,0);
                    printf("buf:%s\n",buf);
                    printf("localAddr = %s\n", localAddr);
                    getsFile(sockfd, localAddr, train.data);
                }
                else{
                    ssize_t sret = recv(sockfd, buf, sizeof(buf), 0);
                    if(sret != 0){
                        printf("buf = %s\n", buf);
                    }
                }

                /* else{ */
                /*     printf("break...\n"); */
                /*     break; */
                /* } */
            }
        }
    }
    /* recvfile(sockfd); */
    close(sockfd);
    return 0;
}
